package com.example.walkingtour;

import java.io.File;
import java.util.GregorianCalendar;
import java.util.List;

import com.example.walkingtour.data.FileRenameService;
import com.example.walkingtour.data.WTDatabase;
import com.example.walkingtour.data.WTProvider;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class WTItemEdit extends Fragment {
	private Button mStartButton, mStopButton, mPlayButton, mCancelButton,
			mDoneButton;

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		assignButtons();// assigns member buttons based on Resource id
		if (!mIsAdd)// for future functionality
		{
			setupForEdit();// will modify UI as necessary for Edit mode
		}

		setupButtonListeners();// sets up button listeners
	}

	private boolean mIsAdd = false;
	private int mAction = 0;

	private LocationListener mLocationListener;

	private int mRowID = 0;
	private String mPath = "", mFile = "", mType = "";
	private long mTime;
	double mLat = 0, mLong = 0;

	LocationManager mLocationManager = null;

	// when switching from Activity to Fragment, Changed this method from:
	// @Override
	// public void onCreate(Bundle savedInstanceState) {
	// super.onCreate(savedInstanceState);
	// setContentView(R.layout.activity_walking_tour_item_edit);
	//
	// mIsAdd = this.setIsAdd();
	// //////////////////////////////////////
	// /////////////To:

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		View view = inflater.inflate(R.layout.activity_walking_tour_item_edit,
				null);
		Bundle b = this.getArguments();
		if (b != null)
			mIsAdd = (b.getInt("MENU_ADD") == WalkingTour.MENU_ADD ? true
					: false);
		// //////////////////////////////////////

		initialGPSsetup();// gets location manager, sets listener, sets lat/long
							// values

		return view;

	}

	/**
	 * initialGPSsetup() Gets LocationManager Defines & sets custom Location
	 * Listener gets location from GPS (if avb) or network sets latitude,
	 * longitude & time based on returned location
	 */
	private void initialGPSsetup() {
		mLocationManager = (LocationManager) this.getActivity()
				.getSystemService(Activity.LOCATION_SERVICE);
		mLocationListener = new LocationListener() {
			public void onLocationChanged(Location location) {
				// Called when a new location is found by the network location
				// provider.
				setGPSvalues(location);
			}

			public void onStatusChanged(String provider, int status,
					Bundle extras) {
			}

			public void onProviderEnabled(String provider) {
			}

			public void onProviderDisabled(String provider) {
			}
		};
		// Register the listener with the Location Manager to receive location
		// updates
		mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
				30000, 3, mLocationListener);

		Location lastKnownLocation = mLocationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		if (lastKnownLocation == null)
			lastKnownLocation = mLocationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		setGPSvalues(lastKnownLocation);
	}

	/**
	 * sets gps member variables mLat & mLong based on the passed location sets
	 * gps member based on passed location, if it errors, it is set based on
	 * current time
	 * 
	 * @param location
	 *            location to set lat & long values to
	 */
	private void setGPSvalues(Location location) {
		try {
			this.mLat = location.getLatitude();
			this.mLong = location.getLongitude();
//			this.mTime = location.getTime();
			Log.d("GPS", "Lat: " + mLat + ", Long: " + mLong + ",   Time: "
					+ mTime);
		} catch (Exception e) {
			e.printStackTrace();
		}
		mTime = (new GregorianCalendar()).getTimeInMillis();
	}

	/**
	 * returns an mAction corresponding to one of the statics defined in
	 * WalkingTourHelper Currently only returns ACTION_TAKE_VIDEO, but will
	 * allow for future functionality
	 * 
	 * @return
	 */
	private int determineAction() {
		// TODO if multiple media types are required, we can use this to setup
		// what mAction is
		// is being performed (video, pic or audio)
		// for now, just returning video
		return WalkingTourHelper.ACTION_TAKE_VIDEO;
	}

	/**
	 * sets up button listeners
	 */
	private void setupButtonListeners() {
		this.mDoneButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				File f = new File(mPath, mFile);
				if (!f.exists()) {
					Toast.makeText(
							v.getContext(),
							"No Recording.  Make a recording, or select cancel",
							Toast.LENGTH_LONG).show();
					return;
				}
				updateDatabase();
				// Changed this code when switching from activity
				// setResult(Activity.RESULT_OK);
				// finish();
				// to this for Fragments
				getActivity().getSupportFragmentManager()
						.popBackStackImmediate();
				// ///////////////////////////////
			}
		});

		this.mStartButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				mAction = determineAction();
				mStartButton.setVisibility(Button.GONE);
				mType = WalkingTourHelper.FILE_EXTENSION[WalkingTourHelper.ACTION_TAKE_VIDEO];

				File file = new File(
						Environment.getExternalStorageDirectory(),
						"wt-video"
								+ mTime
								+ WalkingTourHelper.FILE_EXTENSION[WalkingTourHelper.ACTION_TAKE_VIDEO]);
				mPath = file.getParent();
				mFile = file.getName();
				Log.d("file", mPath + mFile);

				Intent takeVideoIntent = new Intent(
						MediaStore.ACTION_VIDEO_CAPTURE);

				// It seems that even with this line, the camera still saves to
				// standard camera file path
				// thus creating 2 files. Commenting out and using different
				// approach
				// will create standard file name, and rename upon return.
				// takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

				// checks if intent exists before actually starting it
				final PackageManager packageManager = getActivity()
						.getPackageManager();
				List<ResolveInfo> list = packageManager.queryIntentActivities(
						takeVideoIntent, PackageManager.MATCH_DEFAULT_ONLY);
				if (list.size() > 0)
					startActivityForResult(takeVideoIntent, mAction);
				else
					Log.e("camera", "No Video App available");
			}
		});
		// TODO setup for stop recording...only needed when Audio recording is
		// enabled

		this.mPlayButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mAction == WalkingTourHelper.ACTION_TAKE_VIDEO) {
					Intent intent = new Intent(v.getContext(),
							PlayVideoActivity.class);
					File f = new File(mPath, mFile);
					intent.putExtra("path", f.getAbsolutePath());
					startActivity(intent);
				}
			}
		});
		this.mCancelButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				cancelRecording(false);
			}
		});
	}

	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		Uri clipUri;
		if (data == null || resultCode != Activity.RESULT_OK) {
			cancelRecording(false);
			return;
		}
		switch (requestCode) {
		case WalkingTourHelper.ACTION_TAKE_AUDIO:
			// in case recording audio requires a return intent
			break;
		case WalkingTourHelper.ACTION_TAKE_VIDEO:
			mPlayButton.setVisibility(Button.VISIBLE);
			mStopButton.setVisibility(Button.GONE);
			try {
				clipUri = data.getData();
				File mediaFilePath;
				clipUri = WalkingTourHelper.convertContentUriToFileUri(clipUri,
						getActivity());
				if (clipUri.getScheme().equals("file")) {
					TextView tv = (TextView) getActivity().findViewById(
							R.id.time);
					String s;
					s = WalkingTourHelper.getLengthOfRecording(clipUri,
							getActivity());
					tv.setText(s);

					String pathTemp = clipUri.getPath();
					mediaFilePath = new File(pathTemp);

					File myFilePath = new File(mPath, mFile);
					// WalkingTourHelper.renameFile(mediaFilePath, myFilePath);
					Intent renameMediaFileIntent = new Intent(getActivity(),
							FileRenameService.class);
					Bundle b = new Bundle();
					b.putString(FileRenameService.NEW_FILE,
							myFilePath.getAbsolutePath());
					b.putString(FileRenameService.OLD_FILE,
							mediaFilePath.getAbsolutePath());
					renameMediaFileIntent.putExtras(b);
					getActivity().startService(renameMediaFileIntent);

					clipUri = Uri.fromFile(myFilePath);
				} else
					cancelRecording(true);

				/*
				 * String stemp = clipUri.getPath(); File ftemp = new
				 * File(stemp); File newFile = new File (mPath, mFile);
				 * ftemp.renameTo(newFile);
				 */

			} catch (Exception e) {
				e.printStackTrace();
				cancelRecording(true);
			}
			break;
		case WalkingTourHelper.ACTION_TAKE_PIC:
			// will add code here to handle return from take pic
			break;
		}
	}

	/**
	 * This method is used whenever there is an unsuccessful recording this
	 * could be due to user cancel, or runtime exceptions
	 */
	private void cancelRecording(boolean isError) {
		try {
			File f = new File(mPath, mFile);
			f.delete();
		} catch (Exception e) {
			e.printStackTrace();
		}
		Toast.makeText(getActivity(),
				((isError) ? "Error, " : "") + "Recording cancelled",
				Toast.LENGTH_LONG).show();
		// changed this code when switching from Activity
		// setResult(Activity.RESULT_CANCELED);
		// finish();
		// to this code, for fragments
		try {
			getActivity().getSupportFragmentManager().popBackStackImmediate();
		} catch (Exception e) {
			e.printStackTrace();
		}
		// /////////////////////////////////////////
	}

	/**
	 * method assembles the member variables that need to be entered into DB,
	 * and sends them to WTProvider
	 */
	protected void updateDatabase() {
		ContentValues values = new ContentValues();
		values.put(WTDatabase.COL_PATH, this.mPath);
		values.put(WTDatabase.COL_FILE, this.mFile);
		values.put(WTDatabase.COL_GPS_LAT, this.mLat);
		values.put(WTDatabase.COL_GPS_LONG, this.mLong);
		values.put(WTDatabase.COL_RECORDING_TYPE, this.mType);
		values.put(WTDatabase.COL_TIME, this.mTime);

		if (mRowID == 0) {
			Uri newUri = getActivity().getContentResolver().insert(
					WTProvider.CONTENT_URI, values);
			String newID = newUri.getLastPathSegment();
			this.mRowID = Integer.parseInt(newID);
		} else {
			Uri uri = Uri.withAppendedPath(WTProvider.CONTENT_URI,
					String.valueOf(mRowID));
			getActivity().getContentResolver().update(uri, values, null, null);
		}
	}

	/**
	 * This paragraph will have any additional code that is necessary to switch
	 * the activity from being 'add' focused, to providing 'edit' functionality
	 */
	private void setupForEdit() {
		// TODO add any code to this method for
		// adjustments to the ui that would be needed
		// for an 'edit' screen, as opposed to the 'add' screen
	}

	/**
	 * Method to assign Button members based on resource ids
	 */
	private void assignButtons() {
		// Activity a = getActivity();
		// View v = a.findViewById(R.id.startRecording);

		mStartButton = (Button) getView().findViewById(R.id.startRecording);
		mStopButton = (Button) getView().findViewById(R.id.stopRecording);
		mPlayButton = (Button) getView().findViewById(R.id.play);
		mCancelButton = (Button) getView().findViewById(R.id.cancel);
		mDoneButton = (Button) getView().findViewById(R.id.done);

	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		this.mLocationManager.removeUpdates(mLocationListener);
	}

}
